#pragma once

#include "decompose.h"

namespace qbe::editing::Decompose {
void exit(ecs::Query query) {
  auto& param = query.get_resource<DecomposeModel>();
  param.inited = false;
  param.update = false;
  param.entity_hover = entt::null;
  auto& state = query.get_resource<state::State>();
  state.switchMode(state::EditingModeType::None);
}

void exit_callback(ecs::Query query, state::AllModeType mode) {
  auto& param = query.get_resource<DecomposeModel>();
  param.inited = false;
  param.update = false;
  param.entity_hover = entt::null;
  auto& state = query.get_resource<state::State>();
  state.switchMode(state::EditingModeType::None);
}

void init(entt::registry& reg, ecs::Commands commands, ecs::Query query) {
  auto& state = query.get_resource<state::State>();
  state.addExitCall(state::EditingModeType::Decompose, exit_callback);
}

//分解
void update(entt::registry& ecs_reg, ecs::Query query, ecs::Bus& bus) {
  auto& state = query.get_resource<state::State>();
  // 仅在模式执行
  if (state.getEditingMode() != state::EditingModeType::Decompose)
    return;

  auto& cmd = query.get_resource<layout::CellCmd>();
  auto& layout_cmd = query.get_resource<layout::LayoutCmd>();
  auto cell = cmd.get_cell();
  auto& reg = cell->reg;
  auto& cell_state = query.get_resource<layout::CellState>();
  auto& axis_t = query.get_resource<axis::Axis>();
  auto& param = query.get_resource<DecomposeModel>();
  auto& hand = query.get_resource<vsg::ref_ptr<input::HandleBundle>>();
  auto& undoRedoModule = query.get_resource<undoRedoT::UndoRedoModule>();
  select::SelectModel& selectModel = query.get_resource<select::SelectModel>();
  auto& select_event_writer = query.get_event_writer<select::Event>();
  auto& select_cmd = query.get_resource<select::SelectCmd>();
  if (!param.inited) {
    //清除选中状态
    param.inited = true;
    select_cmd.clear_select();
    select_cmd.clear_select_parts();
    select_cmd.clear_hover();
    select_cmd.clear_hover_parts();
  }

  //独立的选择系统
  if (hand->mouse_move) {
    param.entity_hover = entt::null;
    // 鼠标查询范围
    auto r = 30 / axis_t.scale;
    r = r > 30 ? 30 : r;
    select_cmd.set_mouse_range(r);
    auto& x = axis_t.real_x;
    auto& y = axis_t.real_y;
    select_cmd.query_nodes(x, y);
    std::multimap<double, entt::entity> order_borders;
    select_cmd.get_select(x, y, order_borders);
    if (order_borders.size() > 0) {
      auto it_begin = order_borders.begin();
      param.entity_hover = it_begin->second;
    }
    select_cmd.clear_hover();
    if (param.entity_hover != entt::null)
      select_cmd.add_hovers(std::vector<entt::entity>{param.entity_hover});
  }

  if (hand->mousePressed(vsg::ButtonMask::BUTTON_MASK_1)) {
    if (param.entity_hover != entt::null)
      select_cmd.add_selects({param.entity_hover});
  }

  bool clear_select_status = false;
  //清除不合法对象的选中状态
  for (auto [e] : reg.view<select::SelectTag>().each()) {
    auto hover_line = reg.try_get<qlib::Path::s_ptr>(e);
    auto hover_polygon = reg.try_get<qlib::Polygon::s_ptr>(e);
    auto hover_rectangle = reg.try_get<qlib::Rectangle::s_ptr>(e);
    auto hover_fan = reg.try_get<qlib::Fan::s_ptr>(e);
    bool valid_node = (hover_line && (*hover_line)->getLineWidth() == 0) || hover_rectangle || hover_polygon || hover_fan;
    if (!valid_node) {
      reg.remove<select::SelectTag>(e);
      clear_select_status = true;
    }
  }
  if (clear_select_status) {
    select_event_writer.send(select::Event{select::Code::SelectCancel});
  }

  std::vector<double> screen_box = axis_t.getScreenBox();
  //获取选择对象
  std::vector<entt::entity> pre_select;
  for (auto [e] : reg.view<select::HoverTag>().each()) {
    pre_select.push_back(e);
  }

  entt::entity entity_hover = entt::null;  //预选中对象
  if (!pre_select.empty())
    entity_hover = pre_select[0];
  auto selecc_arr = selectModel.getSelectObj();  //选中对象
  auto hover_line = reg.try_get<qlib::Path::s_ptr>(entity_hover);
  auto hover_polygon = reg.try_get<qlib::Polygon::s_ptr>(entity_hover);
  auto hover_rectangle = reg.try_get<qlib::Rectangle::s_ptr>(entity_hover);
  auto hover_fan = reg.try_get<qlib::Fan::s_ptr>(entity_hover);

  //交互逻辑
  bool begin = false;
  bool update = false;
  bool cancel = false;
  bool complete = false;

  if (hand->keyReleased(vsg::KEY_Escape)) {
    cancel = true;  // 按下esc时，退出
  } else if (hand->mousePressed(vsg::ButtonMask::BUTTON_MASK_1)) {
    if (hover_line || hover_polygon || hover_rectangle || hover_fan)
      complete = true;
    else {
      update = true;
      param.update = true;
    }
  } else {
    if (hand->mouse_move) {
      update = true;
      param.update = true;
    }
  }

  if (cancel) {
    //退出模式
    exit(query);
  }
  QString sendOperaterMessageInfo;
  bool valid_node = (hover_line && (*hover_line)->getLineWidth() == 0) || hover_rectangle || hover_polygon || hover_fan;
  if (pre_select.empty()) {
    sendOperaterMessageInfo = QObject::tr("mode: Decompose | Select decomposition objects");
  } else if (valid_node) {
    sendOperaterMessageInfo = QObject::tr("mode: Decompose | Select decomposition objects");
  } else {
    sendOperaterMessageInfo = QObject::tr("mode: Decompose | Invalid Object");
  }
  if (cancel) {
    sendOperaterMessageInfo = "";
  }
  if (complete) {
    //清除选中状态
    select_cmd.clear_select();
    select_cmd.clear_select_parts();
    select_cmd.clear_hover();
    select_cmd.clear_hover_parts();

    //执行分解
    bool node_is_lock = false;                 //line_node->getEleLock()
    entt::entity delete_state = entt::null;    //删除对象
    std::vector<qlib::Path::s_ptr> add_state;  //添加对象
    if (hover_line && !node_is_lock) {
      double line_width = (*hover_line)->getLineWidth();  //line->m_elements[0].m_half_width_and_offset.x * 2;
      std::vector<qlib::Vec2d> point_array = (*hover_line)->spine.points;
      if (line_width == 0 && point_array.size() > 2) {
        for (int i = 0; i < point_array.size() - 1; ++i) {
          std::vector<qlib::Vec2d> points = {point_array[i], point_array[i + 1]};
          qlib::Path::s_ptr path = qlib::Path::create();
          path->spine.points = points;
          path->layer = (*hover_line)->layer;
          add_state.push_back(path);
        }
      } else {
        sendOperaterMessageInfo = QObject::tr("mode: Decompose | Invalid Object");
      }
    } else if (hover_rectangle && !node_is_lock) {
      std::vector<qlib::Vec2d> point_array = (*(*hover_rectangle)->to_polygon()).points;
      for (int i = 0; i < point_array.size(); ++i) {
        std::vector<qlib::Vec2d> points;
        if (i < point_array.size() - 1) {
          points = {point_array[i], point_array[i + 1]};
        } else {
          points = {point_array[i], point_array[0]};
        }
        qlib::Path::s_ptr path = qlib::Path::create();
        path->spine.points = points;
        path->layer = (*hover_rectangle)->layer;
        add_state.push_back(path);
      }
    } else if (hover_polygon && !node_is_lock) {
      std::vector<qlib::Vec2d> point_array = (*hover_polygon)->points;
      for (int i = 0; i < point_array.size(); ++i) {
        std::vector<qlib::Vec2d> points;
        if (i < point_array.size() - 1) {
          points = {point_array[i], point_array[i + 1]};
        } else {
          points = {point_array[i], point_array[0]};
        }
        qlib::Path::s_ptr path = qlib::Path::create();
        path->spine.points = points;
        path->layer = (*hover_polygon)->layer;
        add_state.push_back(path);
      }
    } else if (hover_fan && !node_is_lock) {
      std::vector<qlib::Vec2d> point_array = (*(*hover_fan)->to_polygon()).points;
      {
        std::vector<qlib::Vec2d> points = {point_array[0], point_array[1]};
        qlib::Path::s_ptr path = qlib::Path::create();
        path->spine.points = points;
        path->layer = (*hover_fan)->layer;
        add_state.push_back(path);
      }
      {
        std::vector<qlib::Vec2d> points;
        for (int i = 1; i < point_array.size(); ++i) {
          points.push_back(point_array[i]);
        }
        qlib::Path::s_ptr path = qlib::Path::create();
        path->spine.points = points;
        path->layer = (*hover_fan)->layer;
        add_state.push_back(path);
      }
      {
        std::vector<qlib::Vec2d> points = {point_array[point_array.size() - 1], point_array[0]};
        qlib::Path::s_ptr path = qlib::Path::create();
        path->spine.points = points;
        path->layer = (*hover_fan)->layer;
        add_state.push_back(path);
      }
    } else {
      sendOperaterMessageInfo = QObject::tr("mode: Decompose | Invalid Object");
      // LayoutCtrlData::cancelHighlight(); //取消所有高亮
    }

    //数据修改
    if (!add_state.empty()) {
      undoRedoModule.start(cell);

      for (auto split_path : add_state) {
        //添加对象 并自动整体选中
        entt::entity entity = layout_cmd.add(split_path);
        undoRedoModule.add(entity);
        select_cmd.add_selects({entity});
      }
      //删除分解对象
      if (hover_line || hover_polygon || hover_rectangle || hover_fan) {
        undoRedoModule.dele(entity_hover);
        layout_cmd.remove(entity_hover);
        select_cmd.remove_select(entity_hover);
      }

      undoRedoModule.end();
      param.update = false;
    }
  }
  bus.send<qbe::UiMessage::OperatorInfoMessage>(qbe::UiMessage::OperatorInfoMessage{sendOperaterMessageInfo});
}

void post(entt::registry& reg, ecs::Commands commands, ecs::Query query, ecs::Bus& bus) {}

void DecomposePlugin::build(ecs::App& app) {
  app.init_resource<DecomposeModel>(DecomposeModel{});

  app.add_systems<ecs::stage::Startup>(init);
  app.add_systems<ecs::stage::Update>(update);
  app.add_systems<ecs::stage::PostUpdate>(post);
};

}  // namespace qbe::editing::Decompose